home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / sco / scripts / psn < prev    next >
Encoding:
AWK Script  |  1997-08-26  |  6.4 KB  |  170 lines

  1. #!/usr/local/bin/gawk -f
  2. # @(#) psn.gawk 1.0 96/01/27
  3. # 92/10/06 john@armory.com
  4. # 92/10/12 Convert +'s to -'s in Flags
  5. # 93/06/19 Fixed incorrect references to FieldNums[] as FieldNum[]
  6. #          Changed command field with from 1(?!) to 100
  7. #          Print header
  8. # 96/01/27 Make ps input come from /dev/null to work around gawk+protlib bugs
  9.  
  10. BEGIN {
  11.     for (i = 1; i < ARGC && (ARGV[i] ~ "^[-+]."); i++)
  12.     Flags = Flags " " ARGV[i]
  13.     gsub(/\+/,"-",Flags)
  14.     if (ARGC - i < 1) {
  15.     print \
  16. "psn: No pattern.  Usage: psn [-psflags] search-pattern ...\n" \
  17. "Any processes whose ps line matches any of the given patterns is\n" \
  18. "printed.  Patterns may contains egrep(C)-type regular expressions."
  19.     exit
  20.     }
  21.     for (; ARGC - i < 1; i++)
  22.     Pattern = Pattern "|" ARGV[i]
  23.     Pattern = Pattern ARGV[i]
  24.     Cmd = "echo $$; exec ps -ef " Flags " < /dev/null"
  25.     Cmd | getline shPID
  26.     Cmd | getline Header
  27.     Left = 0
  28.     Right = 1
  29.  
  30.     NumFields = FindColumns(Header,FieldNums,FieldNames,Columns)
  31.     if ("COMMAND" in FieldNums)
  32.     CmdField = "COMMAND"
  33.     else
  34.     CmdField = "CMD"
  35.  
  36.     # Fields that are left-adjusted (at least, the only one we care about)
  37.     # Set to 1 just to put a value integer in Width[].
  38.     Width[CmdField] = 100
  39.  
  40.     FindWidths(FieldNums,FieldNames,Columns,NumFields,Width,Right)
  41.     Command = FieldNums[CmdField]
  42.     if (Command == "") {
  43.     printf "Error: %s not found in header of commmand '%s'.\n",CmdField,Cmd
  44.     exit 1
  45.     }
  46.     PPID = FieldNums["PPID"]
  47.     PID = FieldNums["PID"]
  48.     gsub(" ","|",Pattern)
  49.     # Get all procs before printing anything so we will have the awk prog
  50.     # pid to check against
  51.     while ((Cmd | getline) == 1) {
  52.     # Ignore ps command (same pid as sh because it is exec'ed)
  53.     # but record its parent for comparison
  54.     if ($PID == shPID)
  55.         awkPID = $PPID
  56.     else
  57.         if ($Command ~ Pattern)
  58.         Commands[$PID] = $0
  59.     }
  60.     print Header
  61.     for (Proc in Commands)
  62.     if (Proc != awkPID)
  63.         print Commands[Proc]
  64. }
  65.  
  66. # FindWidths: Find the real width of fields.    92/10/06 john@armory.com
  67. # FindWidths takes information on the starting and ending columns of
  68. # header labels and determines the starting and ending columns of the entire
  69. # field, using information on whether fields are left- or right-adjusted.
  70. #
  71. # Return value: the number of fields found is returned.
  72. # FieldNums[] should contain the number of each field indexed by field name.
  73. # FieldNames[] should contain the name of each field indexed by field number.
  74. # Columns[n,Left] and Columns[n,Right] should contain the left and right 
  75. # columns of the header label for each field.  The values in columns are
  76. # changed, but the column numbers indexes are not updated if they are changed,
  77. # so Columns[] may not be useful after this function is called.
  78. # Column numbers are changed if right- and left-adjusted fields abut in
  79. # such a way as to create a range of columns between them that is not
  80. # allocated to any field.  If this occurs, the column numbers in
  81. # FieldNums[] and the indices of FieldNames[] are changed.
  82. # NumFields should be the number of header labels found.
  83. # DefaultAdj is the adjustment used for fields whose adjustment and width
  84. # is not specified.  It should be set to Left or Right.
  85. # Width[] is used to specify the width of fields which do not have the
  86. # default adjustment.
  87. # If a field name is not in Width[], then the DefaultAdj (Left or Right)
  88. # column of the field is fixed.  If a field name is in Width[], then the other
  89. # column is fixed and the width of the field is Width[fieldname].
  90. # If the rightmost field is left-adjusted, its width is set to 32000.
  91. # Global variables:
  92. # Left and Right should be set to boolean values before this function is
  93. # called (the same values used when FindColumns was called).
  94. # FIELDWIDTHS is set to a string that will cause lines to split into fields
  95. # at points determined by the information supplied to this function.
  96. function FindWidths(FieldNums,FieldNames,Columns,NumFields,Width,DefaultAdj,
  97. NewFieldNames,Num,FWidth,FieldName,Gap) {
  98.     # Set widths given explicitly
  99.     for (FieldName in Width) {
  100.     Num = FieldNums[FieldName]
  101.     if (DefaultAdj == Left)
  102.         Columns[Num,Left] = Columns[Num,Right] - Width[FieldName] + 1
  103.     else
  104.         Columns[Num,Right] = Columns[Num,Left] + Width[FieldName] - 1
  105.     }
  106.     # Set widths not given explicitly
  107.     for (Num = 1; Num <= NumFields; Num++)
  108.     if (!(FieldNames[Num] in Width))
  109.         if (DefaultAdj == Left)
  110.         Columns[Num,Right] = Columns[Num + 1,Left] - 1
  111.         else
  112.         Columns[Num,Left] = Columns[Num - 1,Right] + 1
  113.     # If rightmost field is left adjusted, it will be made negative
  114.     # by the previous loop.  Make it big.
  115.     if (Columns[NumFields,Right] < 1) {
  116.     Columns[NumFields,Right] = 32000
  117.     }
  118.     NewFieldNum = 0
  119.     # Generate value for FIELDWIDTHS,
  120.     # create new fields where right- & left-adjusted fields abut,
  121.     # reset field numbers in FieldNums,
  122.     # create array of field names indexed by new field numbers.
  123.     for (Num = 1; Num <= NumFields; Num++) {
  124.     FWidth = FWidth " " Columns[Num,Right] - Columns[Num,Left] + 1
  125.     FieldName = FieldNames[Num]
  126.     FieldNums[FieldName] = ++NewFieldNum
  127.     NewFieldNames[NewFieldNum] = FieldName
  128.     if ((Gap = Columns[Num + 1,Left] - Columns[Num,Right] - 1) > 0) {
  129.         FWidth = FWidth " " Gap
  130.         NewFieldNum++
  131.     }
  132.     }
  133.     # Set FieldNames to new field numbers.
  134.     if (NewFieldNum > NumFields)
  135.     for (Num = 1; Num <= NewFieldNum; Num++)
  136.         if (Num in NewFieldNames)
  137.         FieldNames[Num] = NewFieldNames[Num]
  138.         else
  139.         delete FieldNames[Num]
  140.     # Discard initial blank.
  141.     FIELDWIDTHS = substr(FWidth,2)
  142.     return NewFieldNum
  143. }
  144.  
  145. # FindColumns: finds the start and end of field names given in a header line.
  146. # Header is separted into field names on FS.
  147. # The number of each field is put in FieldNums[] indexed by the field name.
  148. # The name of each field is put in FieldNames[] indexed by the field number.
  149. # The start and end column is put into Columns[fieldnum,Left] and
  150. # Columns[fieldnum,Right].
  151. # Global variables:
  152. # Left and Right should be set before this function is called.
  153. # Return value: the number of fields found is returned.
  154. function FindColumns(Header,FieldNums,FieldNames,Columns,
  155. Fields,Field,FieldNum,NumFields,StartC,EndC) {
  156.     EndC = 0
  157.     NumFields = split(Header,FieldNames)
  158.     for (FieldNum = 1; FieldNum <= NumFields; FieldNum++) {
  159.     Field = FieldNames[FieldNum]
  160.     FieldNums[Field] = FieldNum
  161.     match(Header,Field)
  162.     StartC = RSTART + EndC
  163.     EndC = StartC + RLENGTH - 1
  164.     Columns[FieldNum,Left] = StartC
  165.     Columns[FieldNum,Right] = EndC
  166.     Header = substr(Header,RSTART + RLENGTH)
  167.     }
  168.     return NumFields
  169. }
  170.